package com.ruoyi.controller;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.CommUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pojo.HistoricActivityInstanceEntity;
import com.ruoyi.pojo.HistoricProcessInstanceEntity;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysUserPostService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("activiti/task")
public class TaskController extends BaseController {

    @Resource
    private TaskService taskService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private ISysUserPostService sysUserPostService;
    @Resource
    private ISysPostService iSysPostService;
    @Resource
    private HistoryService historyService;

    /**
     * 待办事项
     * @param page
     * @param size
     * @return
     */
    @GetMapping("my/waitlist")
    public AjaxResult waitList(@RequestParam("pageNum") Integer page, @RequestParam("pageSize") Integer size){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            return AjaxResult.error("登录信息失效");
        }
        SysUser user = loginUser.getUser();
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(user.getUserName()).listPage((page - 1) * size, size);
        String[] ps = { "id", "name", "createTime"};
        List<Map<String, Object>> listMap = new ArrayList<>();
        tasks.forEach(s -> {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(s.getProcessDefinitionId()).singleResult();

            Map<String, Object> map = CommUtil.obj2map(s, ps);
            map.put("processDefinitionName", processDefinition.getName());
            listMap.add(map);
        });
        return AjaxResult.success(listMap);
    }

    /**
     * 公共事项需认领在处理
     * @param page
     * @param size
     * @return
     */
    @GetMapping("public/list")
    public AjaxResult publicList(@RequestParam("pageNum") Integer page, @RequestParam("pageSize") Integer size){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            return AjaxResult.error("登录信息失效");
        }

        List<SysUserPost> sysUserPosts = sysUserPostService.list(loginUser.getUser().getUserId());
        if (sysUserPosts == null || sysUserPosts.isEmpty()){
            return AjaxResult.success();
        }

        List<String> strings = new ArrayList<>();
        for (SysUserPost sysUserPost:sysUserPosts
             ) {
            SysPost sysPost = iSysPostService.selectPostById(sysUserPost.getPostId());
            if (sysPost != null){
                strings.add(sysPost.getPostCode());
            }

        }
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroupIn(strings).listPage((page - 1) * size, size);
        String[] ps = { "id", "name", "createTime"};
        List<Map<String, Object>> listMap = new ArrayList<>();
        tasks.forEach(s -> {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(s.getProcessDefinitionId()).singleResult();

            Map<String, Object> map = CommUtil.obj2map(s, ps);
            map.put("processDefinitionName", processDefinition.getName());
            listMap.add(map);
        });
        return AjaxResult.success(listMap);
    }

    /**
     * 个人办理事项
     * @param page
     * @param size
     * @return
     */
    @GetMapping("my/list")
    public AjaxResult list(@RequestParam("pageNum") Integer page, @RequestParam("pageSize") Integer size){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            return AjaxResult.error("登录信息失效");
        }

        long count = historyService.createHistoricProcessInstanceQuery().startedBy(loginUser.getUser().getUserId().toString()).count();
        List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().startedBy(loginUser.getUser().getUserId().toString())
                .listPage((page - 1) * size, size);
        List<HistoricProcessInstanceEntity> list = new ArrayList<>();
        historicProcessInstances.forEach(s -> {
            HistoricProcessInstanceEntityImpl historicProcessInstanceEntityImpl = (HistoricProcessInstanceEntityImpl)s;
            HistoricProcessInstanceEntity historicProcessInstanceEntity = new HistoricProcessInstanceEntity();

            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(s.getProcessDefinitionId()).singleResult();
            if (processDefinition != null){
                historicProcessInstanceEntity.setTaskName(processDefinition.getName());
            }

            historicProcessInstanceEntity.setTaskId(s.getProcessDefinitionId());
            historicProcessInstanceEntity.setStartTime(s.getStartTime());
            historicProcessInstanceEntity.setEndTime(s.getEndTime());
            historicProcessInstanceEntity.setProcessInstanceId(historicProcessInstanceEntityImpl.getProcessInstanceId());
            list.add(historicProcessInstanceEntity);
        });

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(count);
        return AjaxResult.success(rspData);
    }

    /**
     * 个人办理事项进度
     * @param processInstanceId
     * @return
     */
    @GetMapping("process/{processInstanceId}")
    public AjaxResult process(@PathVariable String processInstanceId){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            return AjaxResult.error("登录信息失效");
        }

        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .list();
        List<HistoricActivityInstanceEntity> list = new ArrayList<>();
        historicActivityInstances.forEach(s -> {
            HistoricActivityInstanceEntity historicActivityInstanceEntity = new HistoricActivityInstanceEntity();
            historicActivityInstanceEntity.setTaskId(s.getTaskId());
            historicActivityInstanceEntity.setTaskName(s.getActivityName());
            historicActivityInstanceEntity.setStartTime(s.getStartTime());
            historicActivityInstanceEntity.setEndTime(s.getEndTime());
            historicActivityInstanceEntity.setAssignee(s.getAssignee());
            list.add(historicActivityInstanceEntity);
        });

        return AjaxResult.success(list);
    }

    /**
     * 公共事项中认领
     * @param id
     * @return
     */
    @PostMapping("renling/{id}")
    public AjaxResult renling(@PathVariable String id){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            return AjaxResult.error("登录信息失效");
        }

        Task task = taskService.createTaskQuery().taskId(id).singleResult();
        if (task == null){
            return AjaxResult.error("任务不存在，无法认领");
        }

        try {
            taskService.claim(task.getId(), loginUser.getUsername());
        } catch (Exception e) {
            log.error(">>>>>>>>>>>>>任务id:{}认领出错，异常原因：{}", id, e.getMessage());
            return AjaxResult.error("领取失败");
        }
        return AjaxResult.success("认领成功");
    }

    /**
     * 取消认领任务
     * @param id
     * @return
     */
    @PostMapping("cancle_renling/{id}")
    public AjaxResult canleRenLing(@PathVariable String id){
        Task task = taskService.createTaskQuery().taskId(id).singleResult();
        if (task == null){
            return AjaxResult.error("任务不存在");
        }

        try {
            taskService.claim(task.getId(), null);
        } catch (Exception e) {
            log.error(">>>>>>>>>>>>>任务id:{}取消认领出错，异常原因：{}", id, e.getMessage());
            return AjaxResult.error("取消认领失败");
        }
        return AjaxResult.success("取消认领成功");
    }

    /**
     * 待办事项中完成任务
     * @param id
     * @return
     */
    @PostMapping("audit/{id}")
    public AjaxResult audit(@PathVariable String id){
        taskService.complete(id);
        return AjaxResult.success("审核成功");
    }

}
